﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Xna.Framework;

namespace Jemgine.MapEditor
{
    public partial class DockingWindow : Form
    {
        public DockingWindow()
        {
            InitializeComponent();
        }

        EditorState EditorState = null;

        public void SetEditorState(EditorState ES)
        {
            EditorState = ES;
            ES.OnMapLoaded += _OnMapLoaded;
            this.outputControl1.SetEditorState(ES);
            this.mapRenderControl1.SetEditorState(ES);
            this.entityList1.SetEditorState(ES);
            this.properties1.SetEditorState(ES);
            this.operationList1.SetEditorState(ES);
            this.configEditor1.SetEditorState(ES);
            this.buildDialog1.SetEditorState(ES);
            this.toolSelector1.SetEditorState(ES);
            this.keyFrameControl1.SetEditorState(ES);
            ES.OnFileSet += _OnMapLoaded;
            ES.OnSelection += () =>
            {
                this.statusLabel.Text =
                    EditorState.Selected.Type.ToString() + " - "
                    + EditorState.Selected.TopIndex + " "
                    + EditorState.Selected.MiddleIndex + " "
                    + EditorState.Selected.BottomIndex;
            };
        }

        void _OnMapLoaded()
        {
            this.Text = "Jemgine Map Editor - " + EditorState.FileName;
        }

        private void show_texture_list(object sender, EventArgs e)
        {
            //mainDockingControl.TextureListDock.Cancelled = false;
        }

        void ExitMenuClicked(object sender, EventArgs e)
        {
            Close();
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (PromptSaveChanges() == Jemgine.MapEditor.Controls.SaveChanges.Action.Cancel) return;
            EditorState.NewMap();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (PromptSaveChanges() == Jemgine.MapEditor.Controls.SaveChanges.Action.Cancel) return;
            System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
            ofd.Filter = "Data Sources (*.map)|*.map|All Files|*.*";

            if (ofd.ShowDialog(this) == DialogResult.OK)
                EditorState.OpenMap(ofd.FileName);
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (EditorState.FileSet)
                EditorState.SaveMap();
            else
                saveAsToolStripMenuItem_Click(sender, e);
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.SaveFileDialog sfd = new System.Windows.Forms.SaveFileDialog();
            sfd.Filter = "Data Sources (*.map)|*.map|All Files|*.*";

            if (sfd.ShowDialog(this) == DialogResult.OK)
                EditorState.SaveMapAs(sfd.FileName);
        }

        private void edit_delete(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.Delete(EditorState.Selected, EditorState.MultiSelection));
        }

        private void newitem_polygon(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.NewPolygon(EditorState.Selected));
        }

        private void newitem_entity(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.NewMapElement(typeof(Data.EntityRecord), EditorState.RawMousePosition));
        }

        private void newitem_dynamic(object sender, EventArgs e)
        {
            TypeSelector TypeSelector = new TypeSelector(EditorState._config,
                (A) => { return A.IsSubclassOf(typeof(Jemgine.Data.Dynamic)); });
            if (TypeSelector.ShowDialog() == DialogResult.OK)
                EditorState.PerformOperation(new Operations.NewMapElement(TypeSelector.ChoosenType, EditorState.RawMousePosition));
        }

        private void newitem_gear(object sender, EventArgs e)
        {
            CreateGearProperties _settings = new CreateGearProperties();
            GearProperties _gearProperties = new GearProperties(_settings);
            _gearProperties.ShowDialog();
            if (_settings.Cancelled) return;
            EditorState.PerformOperation(new Operations.MakeGear(EditorState.Selected, _settings));
        }

        private void newitem_chunk(object sender, EventArgs e)
        {
            EditorState.PerformOperation(
                new Operations.NewChunk(EditorState.Selected, EditorState.RawMousePosition));
        }

        private void DockingWindow_Load(object sender, EventArgs e)
        {
        }

        private void DockingWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (PromptSaveChanges() == Jemgine.MapEditor.Controls.SaveChanges.Action.Cancel)
            {
                e.Cancel = true;
                return;
            }
        }

        private Controls.SaveChanges.Action PromptSaveChanges()
        {
            if (EditorState.Changes)
            {
                var SaveDialog = new Controls.SaveChanges();
                SaveDialog.ShowDialog();
                var Result = SaveDialog.DialogResult;
                if (Result == Jemgine.MapEditor.Controls.SaveChanges.Action.Cancel)
                    return Jemgine.MapEditor.Controls.SaveChanges.Action.Cancel;
                if (Result == Jemgine.MapEditor.Controls.SaveChanges.Action.Save)
                {
                    if (EditorState.FileSet)
                        EditorState.SaveMap();
                    else
                    {
                        var sfd = new System.Windows.Forms.SaveFileDialog();
                        sfd.Filter = "Data Sources (*.map)|*.map|All Files|*.*";

                        if (sfd.ShowDialog(this) == DialogResult.OK)
                            EditorState.SaveMapAs(sfd.FileName);
                        else
                            return Jemgine.MapEditor.Controls.SaveChanges.Action.Cancel;
                    }
                }
            }
            return Jemgine.MapEditor.Controls.SaveChanges.Action.Discard;
        }


        private void edit_undo(object sender, EventArgs e)
        {
            EditorState.UndoOperation();
        }

        private void mainDockingControl_Load(object sender, EventArgs e)
        {

        }

        private void newitem_component(object sender, EventArgs e)
        {
            Data.EntityRecord Entity = EditorState.GetTopObject(EditorState.Selected) as Data.EntityRecord;
            if (Entity == null) return;

            TypeSelector TypeSelector = new TypeSelector(EditorState._config,
                (A) => {
                    return TypeSelector.FindComponent(A, typeof(Engine.ComponentAttribute)) != null;
                });

            if (TypeSelector.ShowDialog() == DialogResult.OK)
            {
                EditorState.PerformOperation(new Operations.NewComponent(EditorState.Selected, TypeSelector.ChoosenType));
            }
        }

        private void newitem_script_node(object sender, EventArgs e)
        {
            TypeSelector TypeSelector = new TypeSelector(EditorState._config,
                   (A) =>
                   {
                       return TypeSelector.FindComponent(A, typeof(Engine.NodeAttribute)) != null;
                   });
            if (TypeSelector.ShowDialog() == DialogResult.OK)
                EditorState.PerformOperation(new Operations.NewMapElement(TypeSelector.ChoosenType, EditorState.RawMousePosition));
        }

        private void reversePolygonToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.ReversePolygon(EditorState.Selected));
        }


        private void circleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(
    new Operations.NewCircle(EditorState.Selected, EditorState.RawMousePosition));

        }


        private void importMapToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!EditorState.FileSet)
            {
                System.Windows.Forms.MessageBox.Show("Save your map first.");
                return;
            }

            System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
            ofd.Filter = "Data Sources (*.map)|*.map|All Files|*.*";

            if (ofd.ShowDialog(this) == DialogResult.OK)
                EditorState.PerformOperation(new Operations.Import(ofd.FileName));
        }

        private void mergeEntitiesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.MergeEntities(EditorState));
        }

        private void setTintToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Object SelectedObject = EditorState.GetSelectionObject(EditorState.Selected);
            if (SelectedObject == null) return;
            if (SelectedObject is Data.Tintable)
            {
                Data.Tintable Tintable = SelectedObject as Data.Tintable;
                var Picker = new Controls.ColorPicker();
                Picker.SelectedColor = Tintable.GetTint();
                Picker.ShowDialog();
                EditorState.PerformOperation(new Operations.SetTint(Tintable, Picker.SelectedColor));
            }
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<int> Indicies = new List<int>();
            foreach (var Item in EditorState.MultiSelection)
            {
                if (Item.Type != Jemgine.Engine.Selection.Types.MapElement)
                {
                    MessageBox.Show("Multi-Select only top-level map elements. Entities, dynamics, or script nodes.");
                    return;
                }
                Indicies.Add(Item.TopIndex);
            }

            if (Indicies.Count == 0)
            {
                MessageBox.Show("Multi-Select one or more top-level map element.");
                return;
            }

            EditorState.ClipBoard = EditorState.Map.Export(Indicies);
        }

        private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (EditorState.ClipBoard == null) return;
            EditorState.PerformOperation(new Operations.Import(EditorState.ClipBoard));
        }

        private void keyboardControlsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.SpawnHelpWindow("index.html");
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var About = new Controls.About();
            About.ShowDialog();
        }

        private void _cleanCache(String path)
        {
            foreach (var Item in System.IO.Directory.GetFileSystemEntries(path))
            {
                if ((System.IO.File.GetAttributes(Item) & System.IO.FileAttributes.Directory) != 0)
                {
                    _cleanCache(Item);
                    System.IO.Directory.Delete(Item);
                }
                else System.IO.File.Delete(Item);
            }
        }

        private void cleanTextureCacheToolStripMenuItem_Click(object sender, EventArgs e)
        {
            String Cache = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                "Jemgine\\Editor\\Content");
            _cleanCache(Cache);
        }

        private void cloneEntityElementToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.CloneEntityElement(EditorState.Selected));
        }

        private void splineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.NewSpline(EditorState.Selected));
        }

        private void textureShiftUpToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.ModifyTexturing(EditorState.Selected,
                new Data.TextureAlignment { Offset = new Vector2(0, 1) }));
        }

        private void textureShiftDownToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.ModifyTexturing(EditorState.Selected,
                new Data.TextureAlignment { Offset = new Vector2(0, -1) }));
        }

        private void textureShiftRightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.ModifyTexturing(EditorState.Selected,
    new Data.TextureAlignment { Offset = new Vector2(1, 0) }));

        }

        private void textureShiftLeftToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.ModifyTexturing(EditorState.Selected,
    new Data.TextureAlignment { Offset = new Vector2(-1, 0) }));

        }

        private void textureScaleUpToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.ModifyTexturing(EditorState.Selected,
    new Data.TextureAlignment { Scale = new Vector2(1, 1) }));

        }

        private void textureScaleDownToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.ModifyTexturing(EditorState.Selected,
    new Data.TextureAlignment { Scale = new Vector2(-1, -1) }));

        }

        private void textureRotateRightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.ModifyTexturing(EditorState.Selected,
    new Data.TextureAlignment { Angle = 5.0f }));

        }

        private void textureRotateLeftToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.ModifyTexturing(EditorState.Selected,
    new Data.TextureAlignment { Angle = -5.0f }));

        }

        private void assignTextureToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.AssignTexture(EditorState.Selected));
        }

        private void lineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(
    new Operations.NewLine(EditorState.Selected));

        }

        private void openModelEditorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
        }

        private void skeletonToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.NewSkeleton(EditorState.Selected));
        }

        private void quadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditorState.PerformOperation(new Operations.NewQuad(EditorState.Selected));
        }

        private void toolSelector1_ToolPicked(object sender, Controls.ToolSelector.ToolPickedEventArgs e)
        {
            propertyGrid1.SelectedObject = EditorState.SelectedTool;
        }
    }
}
